package net.jiastudy.web.authentication;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;

import cn.hutool.http.HttpUtil;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import net.jiastudy.biz.user.event.UserLoginEvent;
import net.jiastudy.core.common.SecurityConstant;
import net.jiastudy.web.JsonResponseWrapper;

@Component
public class JwtAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

	@Value("${login.jwt.token.expireTime}")
	private Integer tokenExpireTime;

	@Autowired
	protected ApplicationEventPublisher applicationEventPublisher;

	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {

		String username = ((UserDetails) authentication.getPrincipal()).getUsername();
		// 登陆成功生成JWT
		Map<String, Object> claims = new HashMap<>();
		claims.put(SecurityConstant.LOGIN_TIME, System.currentTimeMillis());
		String token = Jwts.builder()
				// 主题 放入用户名
				.setSubject(username).addClaims(claims)
				// 自定义属性 放入用户拥有权限
				// .claim(SecurityConstant.AUTHORITIES, JSON.toJSON(authorities))
				// 失效时间
				.setExpiration(new Date(System.currentTimeMillis() + tokenExpireTime * 60 * 1000))
				// 签名算法和密钥
				.signWith(SignatureAlgorithm.HS512, SecurityConstant.JWT_SIGN_KEY).compact();
		token = SecurityConstant.TOKEN_SPLIT + token;
		ObjectMapper mapper = new ObjectMapper();

		Map<String, String> map = new HashMap<String, String>();
		// map.put("token", request.getSession().getId());
		map.put("token", token);
		response.getWriter().append(mapper.writeValueAsString(new JsonResponseWrapper<Map<String, String>>(map)));
		response.setContentType("application/json");
		response.setStatus(200);
		applicationEventPublisher.publishEvent(
				new UserLoginEvent(authentication.getPrincipal(), HttpUtil.getClientIP(request), new Date()));
	}
}
